﻿#region File Description
///////////////////////////////////////////////////////////////////////////////
/// \file Edge.cs
/// \brief This file stores the Edge and QueuedTransmission class
/// \note This should be sublclassed in application to provide loading functionality
/// \author Bradley Mclain, Steven Duda
/// \date 15/5/2010
/// \remarks Copyright(c) 2010 LM01 Project Group (Animus Games - ViralFlux)
/// \remarks Some Rights Reserved.
/// Licenced under: Microsoft Reciprocal License (Ms-RL)
/// For More Information see: www.microsoft.com/opensource/licenses.mspx
///////////////////////////////////////////////////////////////////////////////
#endregion

#region Using Statements
    using System.Collections.Generic;
#endregion

namespace PropagationEngine
{
    /// <summary>
    /// \class QueuedTransmission
    /// \brief This class allows Transsmissions to be sorted whilst waiting on edges
    /// \author Bradley Mclain, Steven Duda
    /// \date 16/5/2010
    /// </summary>
    internal sealed class QueuedTransmission
    {
        #region Attributes

        internal int ticksTillTransmission;
        internal Transmission transmission;

        #endregion

        #region Methods

        /// <summary>
        /// \author Bradley Mclain, Steven Duda
        /// \brief Constructor for QueuedTransmission
        /// \param transmission The transmission to be queued
        /// \param length The length of the edge we are queuing on
        /// </summary>
        internal QueuedTransmission(Transmission transmission, int length)
        {
            this.transmission = transmission;
            this.ticksTillTransmission = length;
        }

        #endregion
    }

    /// <summary>
    /// \class Edge
    /// \brief This class provides the generic Edge
    /// \note Edges are unidirectional in PropagationEngine
    /// \author Bradley Mclain, Steven Duda
    /// \date 16/5/2010
    /// </summary>
    public class Edge
    {
        #region Attributes

        private List<QueuedTransmission> queue;

        #endregion

        #region Properties

        public Node StartNode { get; private set; }
        public Node EndNode { get; private set; }
        public int Length { get; private set; }

        #endregion

        #region Constructor


        /// <summary>
        /// \author Bradley Mclain, Steven Duda
        /// \brief Constructor for Edge
        /// \param startNode The Node that the edge starts at
        /// \param endNode The Node that the edge ends at
        /// \param length The length of the edge
        /// \date 16/5/2010
        /// </summary>
        public Edge(int length, Node startNode, Node endNode)
        {
            this.Length = length;
            this.StartNode = startNode;
            this.EndNode = endNode;
            this.queue = new List<QueuedTransmission>();
        }

        #endregion

        #region Methods

        /// <summary>
        /// \author Bradley Mclain, Steven Dyda
        /// \brief Updates all Transmissions along queue
        /// \brief Transmits to end Node if required
        /// \date 16/5/2010
        /// </summary>
        public void Tick()
        {
            //Subtract a tick from everything in the queue, if any are zero add them to end node
            foreach (QueuedTransmission queuedTransmission in queue)
                queuedTransmission.ticksTillTransmission--;

            //Fetch list of transmissions ready to transmit
            List<QueuedTransmission> readyToTransmit = queue.FindAll(item => item.ticksTillTransmission <= 0);
            foreach (QueuedTransmission readyTransmission in readyToTransmit)
            {
                this.EndNode.Transmit(readyTransmission.transmission);
            }

            //Remove all ones in queue that have reach zero or less
            this.queue.RemoveAll(item => item.ticksTillTransmission <= 0);

        }

        /// <summary>
        /// \author Bradley Mclain, Steven Duda
        /// \brief Adds a new transmission to the list
        /// \param incomingTransmission The transmission to be queued
        /// \date 16/5/2010
        /// </summary>
        public void Add(Transmission incomingTransmission)
        {
            //Set ticks until transmission, default is length of edge
            QueuedTransmission queuedTransmission = new QueuedTransmission(incomingTransmission, this.Length);
            
            //Take the transmission and add it to the list
            queue.Add(queuedTransmission);
        }

        /// <summary>
        /// \author Steven Duda
        /// \brief Base Implementation: Clears the Edge's Queued Transmission List
        /// \date 05/08/2010
        /// </summary>
        public virtual void Clear()
        {
            this.queue.Clear();
        }


        #endregion

    }
}
